<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>CKEDITOR.dom.walker</title>
	<link rel="stylesheet" type="text/css" href="../../test.css" />
	<script type="text/javascript" src="../../../ckeditor.js"></script>
	<script type="text/javascript" src="../../test.js"></script>
	<script type="text/javascript">
	//<![CDATA[

var tc;

CKEDITOR.test.addTestCase( tc = (function()
{
	// Local reference to the "assert" object.
	var assert = CKEDITOR.test.assert;

	var doc = new CKEDITOR.dom.document( document );

	function assertNodesList( wanted, nodes )
	{
		var simplifiedNodes = [];

		for ( var i = 0 ; i < nodes.length ; i++ )
			simplifiedNodes.push( nodes[i].type == CKEDITOR.NODE_TEXT ? nodes[i].getText() : ( '<' + nodes[i].getName() + '>' ) );

		assert.areSame( wanted.toString(), simplifiedNodes.toString() );
	}

	return {

		test_collapsed : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>Test</p>' );

			var range = new CKEDITOR.dom.range( doc );

			range.setStartAt( node.getFirst(), CKEDITOR.POSITION_AFTER_START );
			range.collapse( true );

			var walker = new CKEDITOR.dom.walker( range );

			assert.isNull( walker.next() );
		},

		test_next_1 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );

			var range = new CKEDITOR.dom.range( doc );
			range.selectNodeContents( node );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.next() ) )
				nodes.push( node );

			assertNodesList( [ '<p>', 'This is ', '<b>', 'a ', '<i>', 'simple', ' test' ], nodes );
		},

		test_next_2 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );

			var range = new CKEDITOR.dom.range( doc );
			range.setStartAt( node.getFirst(), CKEDITOR.POSITION_AFTER_START );
			range.setEnd( node.getChild( [0,1,1,0] ), 2 );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.next() ) )
				nodes.push( node );

			assertNodesList( [ 'This is ', '<b>', 'a ', '<i>', 'si' ], nodes );
		},

		test_next_3 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>Test</p><h1>More</h1>' );

			var range = new CKEDITOR.dom.range( doc );
			range.setStartAt( node.getChild( 1 ), CKEDITOR.POSITION_BEFORE_START );
			range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.next() ) )
				nodes.push( node );

			assertNodesList( [ '<h1>' ], nodes );
		},

		test_next_4 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>Test</p><h1>More</h1>' );

			var range = new CKEDITOR.dom.range( doc );
			range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
			range.setEndAt( node.getChild( 0 ), CKEDITOR.POSITION_AFTER_END );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.next() ) )
				nodes.push( node );

			assertNodesList( [], nodes );
		},

		test_next_5 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>Test</p><h1>More</h1>' );

			var range = new CKEDITOR.dom.range( doc );
			range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
			range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.next() ) )
				nodes.push( node );

			assertNodesList( [ '<h1>' ], nodes );
		},

		test_previous_1 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );

			var range = new CKEDITOR.dom.range( doc );
			range.selectNodeContents( node );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.previous() ) )
				nodes.push( node );

			assertNodesList( [ '<p>', ' test', '<b>', '<i>', 'simple', 'a ', 'This is ' ], nodes );
		},

		test_previous_2 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );

			var range = new CKEDITOR.dom.range( doc );
			range.setEnd( node.getChild( [0,0] ), 2 );
			range.setEnd( node.getChild( [0,1,1,0] ), 2 );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.previous() ) )
				nodes.push( node );

			assertNodesList( [ 'si', 'a ', 'is is ' ], nodes );
		},

		test_previous_3 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>Test</p><h1>More</h1>' );

			var range = new CKEDITOR.dom.range( doc );
			range.setStartAt( node.getChild( 1 ), CKEDITOR.POSITION_BEFORE_START );
			range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.previous() ) )
				nodes.push( node );

			assertNodesList( [ '' ], nodes );
		},

		test_previous_4 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>Test</p><h1>More</h1>' );

			var range = new CKEDITOR.dom.range( doc );
			range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
			range.setEndAt( node.getChild( 0 ), CKEDITOR.POSITION_AFTER_END );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.previous() ) )
				nodes.push( node );

			assertNodesList( [ '<p>' ], nodes );
		},

		test_previous_5 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>Test</p><h1>More</h1>' );

			var range = new CKEDITOR.dom.range( doc );
			range.setStartAt( node.getChild( 0 ), CKEDITOR.POSITION_BEFORE_END );
			range.setEndAt( node.getChild( 1 ), CKEDITOR.POSITION_AFTER_START );

			var walker = new CKEDITOR.dom.walker( range );

			var nodes = [];
			while ( ( node = walker.previous() ) )
				nodes.push( node );

			assertNodesList( [ '<p>' ], nodes );
		},

		/**
		 *  Test guard function is invoked on every move when iterating forward.
		 */
		test_guard_1 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );

			var range = new CKEDITOR.dom.range( doc );
			range.selectNodeContents( node );

			var walker = new CKEDITOR.dom.walker( range );
			var nodes = [];

			walker.guard = function( node )
			{
				nodes.push( node );
				return true;
			};

			while ( ( node = walker.next() ) )
			{ /*jsl:pass*/ }

			assertNodesList( [ '<p>', 'This is ', '<b>', 'a ', '<i>', 'simple', '<i>', '<b>',' test' , '<p>' ], nodes );
		},

		/**
		 *  Test guard function is invoked on every move when iterating backward.
		 */
		test_guard_2 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );

			var range = new CKEDITOR.dom.range( doc );
			range.selectNodeContents( node );

			var walker = new CKEDITOR.dom.walker( range );
			var nodes = [];

			walker.guard = function( node )
			{
				nodes.push( node );
				return true;
			};

			while ( ( node = walker.previous() ) )
			{ /*jsl:pass*/ }

			assertNodesList( [ '<p>', ' test', '<b>', '<i>', 'simple', '<i>', 'a ', '<b>', 'This is ', '<p>' ], nodes );
		},

		/**
		 *  Test evaluator function is invoked on every  step when iterating backward.
		 */
		test_evaluator_1 : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<p>This is <b>a <i>simple</i></b> test</p>' );

			var range = new CKEDITOR.dom.range( doc );
			range.selectNodeContents( node );

			var walker = new CKEDITOR.dom.walker( range );
			var nodes = [];

			walker.evaluator = function( node )
			{
				nodes.push( node );
				return true;
			};

			while ( ( node = walker.previous() ) )
			{ /*jsl:pass*/ }

			assertNodesList( [ '<p>', ' test', '<b>', '<i>', 'simple', 'a ', 'This is ' ], nodes );
		},
		/**
		 * Test walker stop at empty endContainer.
		 */
		test_stopGuard : function()
		{
			var node = doc.getById( 'playground' );
			node.setHtml( '<span></span>afterEnd' );
			var endContainer = node.getFirst();
			var range = new CKEDITOR.dom.range( doc );
			range.selectNodeContents( node );
			range.setEndAt( endContainer, CKEDITOR.POSITION_AFTER_START );

			var walker = new CKEDITOR.dom.walker( range );
			var nodes = [];

			walker.evaluator = function( node )
			{
				nodes.push( node );
				return true;
			};

			while ( ( node = walker.next() ) )
			{ /*jsl:pass*/ }

			assertNodesList( [ '<span>' ], nodes );

		},
		name : document.title
	};
})() );

//window.onload = tc.test_stopGuard;
	//]]>
	</script>
</head>
<body>
	<div id="playground"></div>
</body>
</html>
